local FightSkill = class("FightSkill")
local BuildHelper = require("gameLogic.fight.BuildHelper")
local FightConst = require("const.FightConst")

function FightSkill:ctor(config, entity)
    self._config = config
    self._entity = entity
    self._cooling = 0
    self._isStunt = false -- 是否后天技能
    self:_init()
end

function FightSkill:_init()
    self._target = self._config.target -- 技能目标类型
    self._amount = self._config.amount -- 技能作用人数
    self._cd = self._config.cd
    self._canCounterattack = self._config.canCounterattack == 1
    local element = self._config.element
    if element == 0 then
        element = self._entity:getElement()
    end
    self._hurtStrategy = BuildHelper.buildHurtStrategy(self._config, self, element)
end

function FightSkill:setStunt(stunt)
    self._isStunt = stunt
end

function FightSkill:isStunt()
    return self._isStunt
end

function FightSkill:setCanCounterAttack(canCounterattack)
    self._canCounterattack = canCounterattack
end

function FightSkill:canCounterattack()
    return self._canCounterattack
end

function FightSkill:getTarget()
    return self._target
end

function FightSkill:getEntity()
    return self._entity
end

function FightSkill:getAmount()
    return self._amount
end

function FightSkill:getSkilCooling()
    return self._cooling
end

function FightSkill:resetSkillCooling()
    self._cooling = self._cd
end

function FightSkill:subSkillCooling()
    self._cooling = self._cooling - 1
    self._cooling = self._cooling <= 0 and 0 or self._cooling
end

function FightSkill:getId()
    return self._config.id
end

function FightSkill:getConfig()
    return self._config
end

-- 作用
function FightSkill:actOn(entitys, battleReport)
    self:attackBefore(battleReport)
    if self._entity:isDie() then
        return
    end
    self._entity:getExcuter():recordLastBeAttack(entitys)
    self:_actHurt(entitys, battleReport)
    self:attackAfter(battleReport, entitys)
end

function FightSkill:pureAct(entitys, battleReport)
    if self._entity:isDie() then
        return
    end
    local result = {}
    for i = 1, #entitys do
        local entity = entitys[i]
        local realEntity = self:checkHurtEntity(entity)
        local hurt = self._hurtStrategy:doStrategy(realEntity)
        if realEntity ~= entity then
            hurt:setResist(entity)
        end
        realEntity:simpleHurt(hurt, battleReport)
        table.insert(result, hurt)
    end
    return result
end

function FightSkill:_actHurt(entitys, battleReport)
    for i = 1, #entitys do
        printDebug(self._entity:getDebugName() .. " 攻击 " .. entitys[i]:getDebugName() .. " 技能 " .. self:getId())
        local entity = entitys[i]
        local realEntity = self:checkHurtEntity(entity)
        realEntity:hurtBefore(battleReport)
        local hurt = self._hurtStrategy:doStrategy(realEntity)
        if realEntity ~= entity then
            hurt:setResist(entity)
        end
        self:attackTime(hurt, realEntity, battleReport)
        realEntity:beHurt(hurt, battleReport)
        realEntity:hurtAfter(battleReport, hurt)
        self:attachBuff(realEntity, battleReport)
    end
end

function FightSkill:attackTime(hurt, entity, battleReport)
    local report = battleReport:newAttackTime(entity:getId())
    if hurt.suckBlood > 0 then
        printDebug("FightSkill:attackTime")
        local AttributeConst = require("const.AttributeConst")
        local newHurt =
            require("gameLogic.fight.fightHurtStrategy.Hurt").new(
            hurt.suckBlood,
            false,
            AttributeConst.ELEMENT_TREATMENT,
            false
        )
        self._entity:simpleHurt(newHurt, report)
        report:addSubHurt(newHurt, entity, self._entity)
    end
    G_SignalManager:dispatch(SignalConst.EVENT_ENTITY_ATTACK, self._entity:getId(), entity:getId(), report)
end

function FightSkill:checkHurtEntity(entity)
    local buffManager = self._entity:getExcuter():getBuffManager()
    local newEntity = buffManager:checkResistBuff(entity)
    if newEntity then
        return newEntity
    else
        return entity
    end
end

function FightSkill:attackBefore(battleReport)
    local report = battleReport:newAttackbefore()
    local buffManager = self._entity:getExcuter():getBuffManager()
    buffManager:checkBuffExcuteByEffectTime(FightConst.BUFF_SKILL_ATTACK_B, self._entity, report)
end

function FightSkill:attackAfter(battleReport, entitys)
    local report = battleReport:newAttackAfter()
    local FightConst = require("const.FightConst")
    local buffManager = self._entity:getExcuter():getBuffManager()
    buffManager:checkBuffExcuteByEffectTime(FightConst.BUFF_SKILL_ATTACK_A, self._entity, report)
    self:_skillCallObj(report)
    if self._isStunt then
        G_SignalManager:dispatch(SignalConst.EVENT_SKILL_RELEASE, self._entity:getId(), report)
    end
end

function FightSkill:_skillCallObj(report)
    if self._config.callObj > 0 then
        local SkillCallObj = require("gameLogic.fight.fightSkill.SkillCallObj")
        local callObj = SkillCallObj.new(self._entity, self._config.callObj)
        callObj:call(report)
    end
end

function FightSkill:attachBuff(entity, battleReport)
    local report = battleReport:newHurtAfter(entity:getId())
    local FightConst = require("const.FightConst")
    for i = 1, FightConst.MAX_BUFF do
        if self._config["buff" .. i] > 0 and entity:isFight() then
            local pro = math.random(1, 1000)
            if pro <= self._config["buffPro" .. i] then
                local buff = BuildHelper.buildBuff(self._config["buff" .. i], entity, self._entity)
                buff:setElement(self._config.element)
                local buffManager = self._entity:getExcuter():getBuffManager()
                buffManager:addBuff(buff, report)
            end
        end
    end
end

return FightSkill
